using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;


namespace UnitAssetFramwork.UnitEditor
{
    public class ItemEditorWindow : EditorWindow
    {

        Vector2 scrollPosition;

        SO_ItemDataGroup _ItemDataGroup;
        SO_ItemData _ItemDataSelected;

        const string KeyHistory = "AssetHistory";
        bool isEdit = false;
        bool isBatch = false;
        string _Search;
        List<SO_ItemData> datas;


        readonly GUILayoutOption[] optionView = new GUILayoutOption[] { GUILayout.ExpandHeight(true) };
        readonly GUILayoutOption[] optionMenu = new GUILayoutOption[] { GUILayout.MaxWidth(100) };

        readonly GUILayoutOption[] optionName = new GUILayoutOption[] { GUILayout.Width(100) };
        readonly GUILayoutOption[] optionIcon = new GUILayoutOption[] { GUILayout.Width(150) };
        readonly GUILayoutOption[] optionMode = new GUILayoutOption[] { GUILayout.ExpandWidth(true) };
        readonly GUILayoutOption[] optionLink = new GUILayoutOption[] { GUILayout.ExpandWidth(true) };

        readonly GUILayoutOption[] optionRemove = new GUILayoutOption[] { GUILayout.Width(20), GUILayout.Height(20) };


        readonly GUILayoutOption[] optionDetail = new GUILayoutOption[] { GUILayout.Width(260), GUILayout.ExpandHeight(true) };

        readonly GUILayoutOption[] itemIcon = new GUILayoutOption[] { GUILayout.Width(30), GUILayout.Height(30) };
        readonly GUILayoutOption[] itemRemove = new GUILayoutOption[] { GUILayout.Width(20), GUILayout.Height(20) };

        public event Action<string> OnSearchEventHandler;


        [MenuItem("Framwrok/Editor")]
        public static void ShowWindow()
        {
            var window = GetWindow<ItemEditorWindow>(false, "编辑窗口", true);
            window.minSize = new Vector2(1000, 600);
            window.maxSize = new Vector2(1200, 600);
        }


        public void OnEnable()
        {
            OnSearchEventHandler += OnSearchEvent;
            this.DoOpen();
        }
        public void OnDisable()
        {
            OnSearchEventHandler -= OnSearchEvent;
        }


        
        private void OnGUI()
        {
            GUILayout.BeginVertical();
            {
                DrawMenuBar();
                DrawSearch();

                //DrawViewItem();

                GUILayout.BeginHorizontal(optionView);
                {
                    DrawViewGroup();
                    DrawSelectDetail();
                }
                GUILayout.EndHorizontal();

                this.DoDirty();
            }
            GUILayout.EndVertical();
        }


        Vector2 viewPosition;

        private void DrawViewItem()
        {
            viewPosition = EditorGUILayout.BeginScrollView(viewPosition, GUILayout.Height(150), GUILayout.ExpandWidth(true));
            {
                string[] guidArray = AssetDatabase.FindAssets("t:SO_ItemData");

                Array.ForEach(guidArray, e =>
                {
                    string path = AssetDatabase.GUIDToAssetPath(e);
                    SO_ItemData itemData = AssetDatabase.LoadAssetAtPath<SO_ItemData>(path);

                    EditorGUILayout.BeginVertical();
                    {
                        Texture2D preview = AssetPreview.GetAssetPreview(itemData) ?? EditorGUIUtility.IconContent("d_ScriptableObject Icon").image as Texture2D;

                        EditorLayoutUtil.UniButton(preview, () => EditorGUIUtility.PingObject(itemData), GUILayout.Width(30), GUILayout.Height(30));
                        EditorGUILayout.LabelField(itemData.Name, new GUIStyle() { alignment = TextAnchor.MiddleCenter}, GUILayout.Width(30), GUILayout.Height(30));
                    }
                    EditorGUILayout.EndVertical();

                });
            }
            EditorGUILayout.EndScrollView();
        }



        private void OnSearchEvent(string arg)
        {
            this.datas = !string.IsNullOrEmpty(arg) ?
                _ItemDataGroup != null ? _ItemDataGroup.Datas.FindAll(e => e.Name.Contains(arg)) : new List<SO_ItemData>() :
                _ItemDataGroup != null ? _ItemDataGroup.Datas : new List<SO_ItemData>();
        }



        private void DrawSearch()
        {
            GUILayout.BeginHorizontal("box");
            {
                isEdit = EditorGUILayout.ToggleLeft("启用编辑", isEdit, optionMenu);
                isBatch = EditorGUILayout.ToggleLeft("批量管理", isBatch, optionMenu);
                EditorLayoutUtil.UniButton("新建 ItemData", EditorStyles.toolbarButton, () => DoInsert(), optionMenu);
                EditorLayoutUtil.UniButton("搜索", EditorStyles.toolbarButton, () => this.DoSearch(), optionMenu);
                _Search = EditorGUILayout.TextField(_Search);
            }
            GUILayout.EndHorizontal();
        }
        private void DrawMenuBar()
        {
            GUILayout.BeginHorizontal("box");
            {
                #region 废弃设计
                //EditorLayoutUtil.UniDropdowm("文件",new UnitMenuItem[]
                //{
                //     new(new GUIContent("新建/新建 ItemData"), false, ()=>DoCreate()),
                //     new(new GUIContent("新建/新建 Group"), false, null),
                //     new(new GUIContent("打开"), false, () => DoLoad()),
                //     new(new GUIContent("保存"), false, () => DoSaveOverride(_ItemDataGroup)),
                //     new(new GUIContent("另保存"), false, () =>DoSave(_ItemDataGroup)),
                //});

                //EditorLayoutUtil.UniDropdowm("帮助", new UnitMenuItem[] { new(new GUIContent("访问Gitee"), false, () => Application.OpenURL("https://gitee.com")) });
                //EditorLayoutUtil.UniDropdowm("关于我们", new UnitMenuItem[] { new(new GUIContent("访问Gitee"), false, () => Application.OpenURL("https://gitee.com")) });
                //EditorLayoutUtil.UniDropdowm("检查更新", new UnitMenuItem[] { new(new GUIContent("访问Gitee"), false, () => Application.OpenURL("https://gitee.com")) });
                #endregion


                EditorLayoutUtil.UniButton("新建 Group", EditorStyles.toolbarButton, () => DoCreate(), optionMenu);
                EditorLayoutUtil.UniButton("打开", EditorStyles.toolbarButton, () => DoLoad(), optionMenu);
                EditorLayoutUtil.UniButton("保存", EditorStyles.toolbarButton, () => DoSaveOverride(_ItemDataGroup), optionMenu);
                EditorLayoutUtil.UniButton("另保存", EditorStyles.toolbarButton, () => DoSave(_ItemDataGroup), optionMenu);

                GUILayout.FlexibleSpace();

                EditorLayoutUtil.UniButton("整理输出目录", EditorStyles.toolbarButton, null, optionMenu);
            }
            GUILayout.EndHorizontal();
        }


        private void DrawViewGroup()
        {
            GUILayout.BeginVertical();
            {
                this.DrawViewGroupTitle();
                this.DrawViewGroupContent();
            }
            GUILayout.EndVertical();
        }
        private void DrawViewGroupTitle()
        {
            GUIStyle styleViewTitle = new GUIStyle()
            {
                alignment = TextAnchor.MiddleLeft,
                fontStyle = FontStyle.Bold,
            };

            GUILayout.BeginHorizontal("box");
            {
                EditorGUILayout.LabelField("● 资产名称", styleViewTitle, optionName);
                EditorGUILayout.LabelField("● 关联路径", styleViewTitle, optionLink);
                EditorGUILayout.LabelField("● 关联模型", styleViewTitle, optionMode);
                EditorGUILayout.LabelField("● 关联图标", styleViewTitle, optionIcon);

                if (isBatch)
                {
                    EditorGUILayout.LabelField("", styleViewTitle, optionRemove);
                }
            }
            GUILayout.EndHorizontal();

        }
        private void DrawViewGroupContent()
        {
            if (this.datas == null) return;

            scrollPosition = GUILayout.BeginScrollView(scrollPosition, optionView);
            {
                foreach (var item in this.datas)
                {
                    GUILayout.BeginHorizontal("box");
                    {
                        EditorLayoutUtil.UniButton(true, item.Name, () => this._ItemDataSelected = item, optionName);
                        item.AssetLink = EditorLayoutUtil.UniText(isEdit, item.AssetLink, optionLink);
                        item.GameObject = EditorLayoutUtil.UniObject<GameObject>(isEdit, item.GameObject, optionMode);
                        item.Icon = EditorLayoutUtil.UniObject<Texture2D>(isEdit, item.Icon, optionIcon);

                        if (isBatch)
                        {
                            EditorLayoutUtil.UniButton(EditorGUIUtility.IconContent("d_Toolbar Minus"), () => this._ItemDataGroup.Datas.Remove(item), optionRemove);
                        }
                    }
                    GUILayout.EndHorizontal();
                }
            }
            GUILayout.EndScrollView();


        }
        private void DrawSelectDetail()
        {
            if (_ItemDataSelected == null) return;

            GUILayout.BeginVertical("box", optionDetail);
            {
                EditorLayoutUtil.UniWindowModel(_ItemDataSelected.GameObject, GUILayoutUtility.GetRect(256, 256));
                GUILayout.Space(10);

                _ItemDataSelected.Name = EditorLayoutUtil.UniLabelText(isEdit, "资产名称", _ItemDataSelected.Name);
                _ItemDataSelected.AssetLink = EditorLayoutUtil.UniLabelText(isEdit, "加载路径", _ItemDataSelected.AssetLink);

                _ItemDataSelected.Icon = EditorLayoutUtil.UniLabelObject<Texture2D>(isEdit, "关联图标", _ItemDataSelected.Icon);
                _ItemDataSelected.GameObject = EditorLayoutUtil.UniLabelObject<GameObject>(isEdit, "关联模型", _ItemDataSelected.GameObject);

                GUILayout.Space(10);

                _ItemDataSelected.Description = EditorLayoutUtil.UniLabelTextArea(isEdit, "内容描述", _ItemDataSelected.Description);
            }
            GUILayout.EndVertical();
        }



        private void DoSearch()
        {
            OnSearchEventHandler?.Invoke(this._Search);
        }
        private void DoOpen()
        {
            string path = EditorPrefs.GetString(KeyHistory, string.Empty);

            if (!string.IsNullOrEmpty(path))
            {
                path = path.Replace(Application.dataPath, "Assets");
                _ItemDataGroup = AssetDatabase.LoadAssetAtPath<SO_ItemDataGroup>(path);

                this.datas = this._ItemDataGroup.Datas;

                this.DoCache();
            }
        }
        private void DoInsert()
        {
            if (_ItemDataGroup == null) return;

            _ItemDataGroup.Datas ??= new();

            SO_ItemData @new = ScriptableObjectUtil.Create<SO_ItemData>($"Output/Asset Framwork/ItemData");
            if (@new == null) return;

            _ItemDataGroup.Datas.Insert(0, @new);

            EditorUtility.SetDirty(this._ItemDataGroup);
        }
        private void DoCreate()
        {
            _ItemDataGroup = ScriptableObjectUtil.Create<SO_ItemDataGroup>($"Output/Asset Framwork/ItemDataGroup");

            _ItemDataGroup.Description = "待描述";
            _ItemDataGroup.Datas = new List<SO_ItemData>();

            string path = AssetDatabase.GetAssetPath(_ItemDataGroup);

            EditorPrefs.SetString(KeyHistory, $"{Application.dataPath}/{path}");
            this.datas = _ItemDataGroup.Datas;
        }
        private void DoLoad()
        {
            string path = EditorUtility.OpenFilePanel("保存", "Assets", "asset");
            if (!string.IsNullOrEmpty(path))
            {
                path = path.Replace(Application.dataPath, "Assets");

                _ItemDataGroup = AssetDatabase.LoadAssetAtPath<SO_ItemDataGroup>(path);

                EditorUtility.SetDirty(_ItemDataGroup);
                EditorPrefs.SetString(KeyHistory, path);
            }
        }


        private void DoSave(SO_ItemDataGroup group)
        {
            string path = EditorUtility.SaveFilePanel("保存", "Assets", "NewItemDataGroup", "asset");
            if (!string.IsNullOrEmpty(path))
            {
                path = path.Replace(Application.dataPath, "Assets");
                AssetDatabase.CreateAsset(group, path);
                AssetDatabase.SaveAssets();

                this.DoCache();
                EditorPrefs.SetString(KeyHistory, path);
            }
        }
        private void DoSaveOverride(SO_ItemDataGroup group)
        {
            this.DoCache();
        }
        private void DoCache()
        {
            AssetDatabase.Refresh();

            if (_ItemDataGroup != null)
            {
                EditorUtility.SetDirty(_ItemDataGroup);
            }
        }
        private void DoDirty()
        {
            if (_ItemDataGroup == null) return;

            if (EditorGUI.EndChangeCheck())
            {
                _ItemDataGroup.Datas.ForEach(e => EditorUtility.SetDirty(e));

                EditorUtility.SetDirty(_ItemDataGroup);
            }
        }
    }
}